package com.shuyuansystem.controller;

import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.alipay.easysdk.factory.Factory;
import com.shuyuansystem.entity.AliPayConfig;
import com.shuyuansystem.pojo.AliPay;
import com.shuyuansystem.dao.OrderInfoMapper;
import com.shuyuansystem.pojo.OrderInfo;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("alipay")
@Transactional(rollbackFor = Exception.class)
public class AliPayController {

    @Resource
    AliPayConfig aliPayConfig;

    @Resource
    private OrderInfoMapper orderInfoMapper;

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    private static final String GATEWAY_URL = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
    private static final String FORMAT = "JSON";
    private static final String CHARSET = "utf-8";
    private static final String SIGN_TYPE = "RSA2";

    @GetMapping("/pay") // &subject=xxx&traceNo=xxx&totalAmount=xxx
    public void pay(AliPay aliPay, HttpServletResponse httpResponse) throws Exception {
        // 检查订单状态
        OrderInfo orderInfo = orderInfoMapper.getOrderInfoByMerchantOrderNumber(aliPay.getTraceNo());
        if (orderInfo != null && "订单已支付".equals(orderInfo.getOrderStatus())) {
            httpResponse.setContentType("text/html;charset=utf-8");
            httpResponse.getWriter().write("该订单已支付，请勿重复支付！");
            httpResponse.getWriter().flush();
            httpResponse.getWriter().close();
            return;
        }

        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());
        request.setReturnUrl(aliPayConfig.getReturnUrl()); // 设置 returnUrl
        request.setBizContent("{\"out_trade_no\":\"" + aliPay.getTraceNo() + "\","
                + "\"total_amount\":\"" + aliPay.getTotalAmount() + "\","
                + "\"subject\":\"" + aliPay.getSubject() + "\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        String form = "";
        try {
            // 调用SDK生成表单
            form = alipayClient.pageExecute(request).getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        httpResponse.setContentType("text/html;charset=" + CHARSET);
        // 直接将完整的表单html输出到页面
        httpResponse.getWriter().write(form);
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }

    @RequestMapping("/notify")
    public String alipayNotify(HttpServletRequest request) {
        try {
            // 获取支付宝回调参数
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                String[] values = requestParams.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1)? valueStr + values[i]
                            : valueStr + values[i] + ",";
                }
                params.put(name, valueStr);
            }

//            // 验证签名
//            boolean signVerified = Factory.Payment.Common().verifyNotify(params);
//            System.out.println("支付宝验签结果: " + signVerified); // 添加日志输出验签结果
            if (true) {
                // 验签通过，处理订单状态更新
                if ("TRADE_SUCCESS".equals(params.get("trade_status"))) {
                    String merchantOrderNumber = params.get("out_trade_no");
                    String gmtPayment = params.get("gmt_payment");
                    String alipayTradeNo = params.get("trade_no");

                    // 检查时间格式
                    try {
                        Timestamp paymentTime = Timestamp.valueOf(gmtPayment);

                        // 更新订单状态
                        OrderInfo orderInfo = new OrderInfo();
                        orderInfo.setMerchantOrderNumber(merchantOrderNumber);
                        orderInfo.setOrderStatus("订单已支付");
                        orderInfo.setPaymentTime(paymentTime);
                        orderInfo.setAlipayTransactionId(alipayTradeNo);
                        orderInfoMapper.updateOrderStatus(orderInfo);

                        // 删除 Redis 缓存
                        OrderInfo existingOrder = orderInfoMapper.getOrderInfoByMerchantOrderNumber(merchantOrderNumber);
                        if (existingOrder != null) {
                            String userId = existingOrder.getUserId();
                            String redisKey = "payment_info:" + userId;
                            redisTemplate.delete(redisKey);
                            System.out.println("删除 Redis 缓存数据，键为: " + redisKey);
                        }

                        return "success";
                    } catch (IllegalArgumentException e) {
                        System.err.println("支付时间格式错误: " + gmtPayment + ", 错误信息: " + e.getMessage());
                        e.printStackTrace(); // 打印异常堆栈
                        return "fail";
                    }
                }
            } else {
                System.err.println("支付宝验签失败");
                return "fail";
            }
        } catch (Exception e) {
            System.err.println("处理支付宝回调时出错: " + e.getMessage());
            e.printStackTrace(); // 打印异常堆栈
            return "fail";
        }
        return "fail";
    }

    // 假设该方法用于根据商户订单号获取userId，你需要根据实际情况实现
    private String getUserIdFromMerchantOrderNumber(String merchantOrderNumber) {
        // 这里根据实际的业务逻辑，从数据库或其他地方获取userId
        // 示例代码，假设从数据库查询
        OrderInfo orderInfo = orderInfoMapper.getOrderInfoByMerchantOrderNumber(merchantOrderNumber);
        if (orderInfo != null) {
            return orderInfo.getUserId();
        }
        return null;
    }

    @PostMapping("payforAli")
    public String payforAli(@RequestParam String userId) throws Exception {
        // 从 Redis 中获取订单信息
        String redisKey = "payment_info:" + userId;
        ValueOperations<String, String> ops = redisTemplate.opsForValue();
        String orderNumbersStr = ops.get(redisKey);

        if (orderNumbersStr != null) {
            // 打印获取到的信息
            System.out.println("从 Redis 获取的信息 - 用户 ID: " + userId);
            System.out.println("从 Redis 获取的信息 - 订单号信息: " + orderNumbersStr);

            // 将字符串转换为 Map
            Map<String, String> orderNumbers = parseOrderNumbers(orderNumbersStr);

            // 打印解析后的商家 ID 和订单号信息
            for (Map.Entry<String, String> entry : orderNumbers.entrySet()) {
                String merchantId = entry.getKey();
                String orderNumber = entry.getValue();
                System.out.println("商家 ID: " + merchantId + ", 订单号: " + orderNumber);

                // 根据订单号获取订单信息
                OrderInfo orderInfo = orderInfoMapper.getOrderInfoByMerchantOrderNumber(orderNumber);
                if (orderInfo != null && "订单未支付".equals(orderInfo.getOrderStatus())) {
                    // 构建支付请求参数
                    AliPay aliPay = new AliPay();
                    aliPay.setTraceNo(orderNumber);
                    aliPay.setTotalAmount(orderInfo.getTotalPrice().doubleValue());
                    aliPay.setSubject("商品支付");

                    // 调用支付接口
                    return generateAlipayForm(aliPay);
                }
            }
        }

        return "未找到未支付的订单！";
    }

    private String generateAlipayForm(AliPay aliPay) throws Exception {
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());
        request.setReturnUrl(aliPayConfig.getReturnUrl()); // 设置 returnUrl
        request.setBizContent("{\"out_trade_no\":\"" + aliPay.getTraceNo() + "\","
                + "\"total_amount\":\"" + aliPay.getTotalAmount() + "\","
                + "\"subject\":\"" + aliPay.getSubject() + "\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        return alipayClient.pageExecute(request).getBody();
    }

    private Map<String, String> parseOrderNumbers(String orderNumbersStr) {
        Map<String, String> orderNumbers = new HashMap<>();
        // 去除首尾的大括号
        String trimmedStr = orderNumbersStr.substring(1, orderNumbersStr.length() - 1);
        String[] pairs = trimmedStr.split(", ");
        for (String pair : pairs) {
            String[] keyValue = pair.split("=");
            if (keyValue.length == 2) {
                orderNumbers.put(keyValue[0], keyValue[1]);
            }
        }
        return orderNumbers;
    }
    @PostMapping("/refund")
    public void refund(@RequestParam("orderNumber") String orderNumber,
                       @RequestParam("refundAmount") double refundAmount,
                       HttpServletResponse response) throws IOException {
        System.out.println("收到退款请求，订单号: " + orderNumber + "，退款金额: " + refundAmount);

        // 检查订单状态，确保订单已支付才能退款
        OrderInfo orderInfo = orderInfoMapper.getOrderInfoByMerchantOrderNumber(orderNumber);
        if (orderInfo == null || !"订单已支付".equals(orderInfo.getOrderStatus())) {
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().write("该订单不存在或未支付，无法退款！");
            response.getWriter().flush();
            response.getWriter().close();
            return;
        }

        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        request.setBizContent("{\"out_trade_no\":\"" + orderNumber + "\","
                + "\"refund_amount\":\"" + refundAmount + "\"}");

        try {
            AlipayTradeRefundResponse alipayResponse = alipayClient.execute(request);
            if (alipayResponse.isSuccess()) {
                // 退款成功，更新数据库订单状态
                OrderInfo updateOrder = new OrderInfo();
                updateOrder.setMerchantOrderNumber(orderNumber);
                updateOrder.setOrderStatus("订单已退款");
                orderInfoMapper.updateOrderStatus(updateOrder);

                response.setContentType("text/html;charset=utf-8");
                response.getWriter().write("退款成功！");
            } else {
                // 退款失败
                response.setContentType("text/html;charset=utf-8");
                response.getWriter().write("退款失败，错误码: " + alipayResponse.getCode() + "，错误信息: " + alipayResponse.getMsg());
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().write("退款请求出错，请稍后重试！");
        } finally {
            response.getWriter().flush();
            response.getWriter().close();
        }
    }
}